
package Math;

import java.lang.*;

/* Start of 'Stock' class */
public final class Stock
{
  private Object Bulk[];
  private int AllocSize, Size, MaxSize;
  private Class cl = null;
  /* 'Stock' class constructor
   * ARGUMENTS: None.
   * RETURNS: None.
   */
  public Stock( int AllocSize )
  {
    this.AllocSize = AllocSize;
  } /* End of 'Stock' function */

  /* Add element to stock
   * ARGUMENTS:
   *   - adding element
   *       Object Dt;
   * RETURNS:
   *   - self reference
   *       Stock;
   */
  public Stock Add( Object Dt )
  {

    if (cl == null)
      cl = Dt.getClass();
    if (Size == MaxSize)
    {

       Object NewBulk[] = new Object[Size + AllocSize];
      if (Bulk != null)
        System.arraycopy(Bulk, 0, NewBulk, 0, Size);
      Bulk = NewBulk;
      MaxSize += AllocSize;
    }
    Bulk[Size++] = Dt;

    return this;
  } /* End of 'Add' function */

  /* Add elements to stock
   * ARGUMENTS:
   *   - add elements array
   *       Object Dt[];
   *   - add elements number
   *       int Num;
   * RETURNS:
   *   - self reference
   *       Stock;
   */
  public Stock Add( Object Dt[], int Num )
  {
    for (int i = 0; i < Num; i++)
      Add(Dt[i]);

    return this;
  } /* End of 'Add' function */

  /* Add elements array to stock
   * ARGUMENTS:
   *   - array with add elemts
   *       Object Dt[];
   * RETURNS:
   *   - self reference
   *       Stock;
   */
  public Stock Add( Object Dt[] )
  {
    Add(Dt, Dt.length);

    return this;
  } /* End of 'Add' function */

  public Stock Set( int Num, Object Dt )
  {
    if (Num < Size)
      Bulk[Num] = Dt;
    return this;
  }

  /* Get stock element
   * ARGUMENTS:
   *   - element number
   *       int Num;
   * RETURNS:
   *   - element from stock
   *       Objectect;
   */
  public Object Get( int Num )
  {
    if (Num < 0 || Num >= Size)
      return null;
    return Bulk[Num];
  } /* End of 'Get' function */

  /* Get stock size
   * ARGUMENTS: None.
   * RETURNS:
   *   - stock size
   *       int;
   */
  public int Size( )
  {
    return Size;
  } /* End of 'Size' function */

  /* Delte last element from stock
   * ARGUMENTS: None.
   * RETURNS:
   *   - self reference
   *       Stock;
   */
  public Stock DeleteLast( )
  {
    if (Size != 0)
      Size--;

    return this;
  } /* End of 'DeleteLast' function */

  /* Delete element in stock by number
   * ARGUMENTS:
   *   - element number
   *       int Num;
   * RETURNS:
   *   - self reference
   */
  public Stock DeleteNum( int Num )
  {
    if (Num >= 0 && Num < Size )
    {
      if (Num != Size - 1)
        System.arraycopy(Bulk, Num + 1, Bulk, Num, Size - Num - 1);
      Size--;
      Realloc();
    }
    return this;
  } /* End of 'DeleteNum' function */

  /* Delete stock elements in interval
   * ARGUMENTS: 
   *   - interval start and end
   *       int From, To;
   * RETURNS:
   *   - self reference 
   *       Stock;
   */
  public Stock DeleteInterval( int From, int To )
  {
    if (From < 0)
      From = 0;
    if (To < 0)
      To = 0;
    if (To < From)
    {
      int Inc = To;
      To = From;
      From = Inc;
    }
    if (To >= Size - 1)
      Size = From;
    else
    {
      System.arraycopy(Bulk, To + 1, Bulk, From, Size - To - 1);
      Size -= To - From + 1;
    }
    Realloc();
    return this;
  } /* End of 'DeleteInterval' function */

  /* Get all stock elements function
   * ARGUMENTS: None.
   * RETURNS:
   *   - array of stock elements
   *       Object[];
   */
  public Object[] GetAll( )
  {
    Object Mas[] = new Object[Size];
    System.arraycopy(Bulk, 0, Mas, 0, Size);
    return Mas;
  } /* End of 'GetAll' function */

  /* Realloc stock`s memory function
   * ARGUMENTS: None.
   * RETURNS: None.
   */
  private void Realloc( )
  {
    if (MaxSize - Size > 2 * AllocSize)
    {
      Object NewBulk[] = new Object[Size + AllocSize];
      System.arraycopy(Bulk, 0, NewBulk, 0, Size);
      Bulk = NewBulk;
      MaxSize = Size + AllocSize;
    }
  } /* End of 'Realloc' function */

  /* Kill all elements in stock
   * ARGUMENTS: None.
   * RETURNS:
   *   - self reference
   *       Stock;
   */
  public Stock Free( )
  {
    Bulk = null;
    Size = 0;
    MaxSize = 0;
    
    return this;
  } /* End of 'Stock' function */

} /* End of 'Stock' class */
